package com.nulldev.util.web.nCaptcha.captchas.shapes;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import com.nulldev.util.image.ImageUtil;
import com.nulldev.util.image2.textobf.TextObf;
import com.nulldev.util.image2.textobf.TextObf.ObfuscationMethod;
import com.nulldev.util.java.DataSet;
import com.nulldev.util.java.utils.color.ColorUtil;
import com.nulldev.util.math.MathUtil;
import com.nulldev.util.string.StringsUtil;
import com.nulldev.util.web.nCaptcha.backend.Captcha;

public class ShapeIdentification implements Captcha {

	@Override
	public DataSet<String, String[]> generateBase64Image(final int botLevel) {
		final String shapeForInt = shapeForInt(MathUtil.randInt(0, 3));
		final BufferedImage bf = ImageUtil.createFromColorImg(Color.white, 100, 80);
		final Graphics g = bf.createGraphics();
		// use transparency to make hell for bots
		((Graphics2D)g).setComposite(AlphaComposite.SrcOver.derive(MathUtil.randFloat(0, 1)));
		if (shapeForInt.equals("square")) {
			g.setColor(ColorUtil.randomColor(MathUtil.randInt(0, 255)));
			g.fillRect(5, 5, 60, 60);
		}else if (shapeForInt.equals("circle")) {
			g.setColor(ColorUtil.randomColor(MathUtil.randInt(0, 255)));
			g.fillOval(5, 5, 70, 70);
		}else if (shapeForInt.equals("arc")) {
			g.setColor(ColorUtil.randomColor(MathUtil.randInt(0, 255)));
			g.fillArc(5, 5, 70, 70, 60, 120);
		}else if (shapeForInt.equals("rectangle")) {
			g.setColor(ColorUtil.randomColor(MathUtil.randInt(0, 255)));
			g.fillRoundRect(5, 5, 90, 70, 5, 5);
		}
		// increase bot difficulty.
		// level 1
		for (int i = 0; i < bf.getWidth() / 2; i++) {
			g.setColor(ColorUtil.randomColor());
			g.drawRect(MathUtil.randInt(0, bf.getWidth()), MathUtil.randInt(0, bf.getHeight()), 1, 1);
		}
		// level 2
		for (int i = 0; i < bf.getWidth() / 2; i++) {
			g.setColor(ColorUtil.randomColor());
			g.drawRect(MathUtil.randInt(0, bf.getWidth()), MathUtil.randInt(0, bf.getHeight()), 1, 1);
		}
		// make harder to identify.
		for (int i = 0; i < bf.getWidth() / 2; i++) {
			g.setColor(ColorUtil.randomColor());
			g.drawRect(MathUtil.randInt(0, bf.getWidth()), MathUtil.randInt(0, bf.getHeight()), 1, 1);
		}
		for (int i = 0; i < bf.getWidth() / 2; i++) {
			g.setColor(ColorUtil.randomColor());
			g.drawRect(MathUtil.randInt(0, bf.getWidth()), MathUtil.randInt(0, bf.getHeight()), 1, 1);
		}
		g.dispose();
		final BufferedImage bf2 = TextObf.obfuscateImage(bf, (botLevel > 2 ? ObfuscationMethod.Noise : ObfuscationMethod.PixelObfuscation));
		final String b64 = ImageUtil.convertImageDataBase64(bf2);
		return new DataSet<String, String[]>("data:image/png;base64," +  b64, new String[] {
				shapeForInt, shapeForInt.toUpperCase(), StringsUtil.capitalizeString(shapeForInt)});
	}

	@Override
	public String getType() {
		return "shapes";
	}
	
	private String shapeForInt(final int i) {
		if (i == 0) {
			return "square";
		}else if (i == 1) {
			return "circle";
		}else if (i == 2) {
			return "arc";
		}else if (i == 3) {
			return "rectangle";
		}
		return "square";
	}

}
